package com.atguigu.mybatis.demo;

import com.atguigu.mybatis.bean.Employee;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * Created by Smexy on 2022/9/6
 *
 *      helloworld案例以查询数据库中指定id的员工为例。
 *
 *      JDBC:   ①有一个Connection
 *              ②准备sql
 *              ③获取一个PrepqredStatement
 *              ④预编译sql，填充占位符
 *              ⑤执行查询，获取返回值
 *              ⑥解析返回值，将返回值封装为Bean
 *              ⑦关闭连接
 *
 *              Connection负责把客户端的SQL发送给Mysql服务端
 *
 *      Mybatis:    ②准备sql. 编写在一个xml文件中。在全局配置中进行注册(告诉mybatis，在某个文件中有sql)
 *
 *              SqlSession:  负责把客户端的SQL发送给Mysql服务端。
 *                              套路代码。
 *
 *     ---------------------------------------
 *      封装规则：
 *               select * from tbl_employee where id = #{jljaelkjfalkfj}
 *               查询的结果
 *   id  last_name(lastName)  gender  email
 * ------  ---------  ------  --------------
 *      1  Tom        male    Tom@163.com
 *
 *              在执行sql时，会根据sql的resultType来确定每一行要封装的类型，会使用反射创建指定类型的Bean
 *                     Employee e = new Employee()
 *
 *              封装属性时，根据列名，调用 bean的 set列名(列值)
 *                          e.setId(1);
 *                          e.setLast_name('Tom');
 *                          e.setGender('male');
 *                          e.setEmail('Tom@163.com')
 *
 *
 *   ------------------------------
 *      目前方式的问题:
 *          ①不符合接口式编程的原则。
 *                  有一个Dao（数据库访问对象），对数据库的CRUD的方法，声明在Dao中。而现在直接使用SqlSession提供的方法
 *          ②不能将就的问题:
 *                  调用的是SqlSession提供的方法，无法对入参进行类型检查，在执行时，就可能发生运行时异常
 *                  返回值类型不是想要的类型，还得强转下
 *
 *
 *
 *       解决思路：  自己定义方法，类型由你方法的参数列表确定有类型检查。
 *                  自己定义方法，明确声明返回值类型，返回值声明什么类型，就返回什么类型，不用转换。
 *
 *                  接口式编程。
 *
 *   ----------------------------
 *      习惯： 在mybatis中，习惯把 Dao 称为 Mapper
 *              把编写sql的xml文件称为  mapper
 *
 *
 *
 */
public class HelloWorld
{

    public static void main(String[] args) throws IOException {

            //准备SqlSessionFactory
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

            //获取SqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();

        /*
                使用sqlSession发送sql

                selectOne(String statement, Object parameter)
                    statement: 要发送给mysql的sql语句的id(xml的namespace.sqlid)
                    parameter: 给sql传入的参数
         */
        Object o = sqlSession.selectOne("feichangbang.sql1", sqlSessionFactory);

        Employee employee = (Employee) o;

        System.out.println(employee);


        sqlSession.close();


    }
}
